package io.renren.service.impl;

import cn.hutool.core.util.IdUtil;
import com.alibaba.druid.util.StringUtils;
import com.wechat.pay.java.core.notification.NotificationConfig;
import com.wechat.pay.java.core.notification.NotificationParser;
import com.wechat.pay.java.core.notification.RequestParam;
import com.wechat.pay.java.service.partnerpayments.jsapi.JsapiServiceExtension;
import com.wechat.pay.java.service.partnerpayments.jsapi.model.Payer;
import com.wechat.pay.java.service.partnerpayments.nativepay.model.*;

import com.wechat.pay.java.service.partnerpayments.nativepay.NativePayService;
import io.renren.common.utils.WxUtil;
import io.renren.config.WxPayAutoCertificateConfig;
import io.renren.config.WxPayConfig;
import io.renren.service.WxPayService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @ClassName WxPayServiceImpl
 * @Description TODO
 * @Author Jll
 * @Date 2024/6/18 16:33
 * @Version 1.0
 */
@Service
@Slf4j
public class WxPayServiceImpl implements WxPayService {

    @Resource
    private WxPayAutoCertificateConfig wxPayAutoCertificateConfig;

    @Resource
    private WxPayConfig wxPayConfig;

    private final ReentrantLock lock = new ReentrantLock();

    @Override
    public Map<String, Object> partnerPaymentsNativePay() {
        // 构建service
        NativePayService service = new NativePayService.Builder().config(wxPayAutoCertificateConfig.rsaAutoCertificateConfig()).build();
        PrepayRequest request = new PrepayRequest();
        //【服务商公众号ID】 服务商公众号ID
        request.setSpAppid(wxPayConfig.getGzhAppId());
        //【服务商户号】 服务商户号
        request.setSpMchid(wxPayConfig.getMerchantId());
        //【子商户号/二级商户号】 子商户/二级商户的商户号，由微信支付生成并下发。
        request.setSubMchid("1673936453");
        //【商品描述】 商品描述
        request.setDescription("支付手续费");
        //【商户订单号】 商户系统内部订单号，只能是数字、大小写字母_-*且在同一个商户号下唯一
        request.setOutTradeNo(IdUtil.simpleUUID());
        //【订单金额】 订单金额
        Amount amount = new Amount();
        amount.setCurrency("CNY");
        amount.setTotal(1);
        request.setAmount(amount);
        request.setNotifyUrl(wxPayConfig.getPayNotifyUrl());
        // 调用下单方法，得到应答
        PrepayResponse response = service.prepay(request);
        // 使用微信扫描 code_url 对应的二维码，即可体验Native支付
        System.out.println(response.getCodeUrl());
        Map<String, Object> map = new HashMap<>(1);
        map.put("codeUrl", response.getCodeUrl());
        return map;
    }

    @Override
    public void payCallback(HttpServletRequest request, HttpServletResponse response) throws IOException {
        //获取报文
        String body = WxUtil.getRequestBody(request);
        //随机串
        String nonceStr = request.getHeader("Wechatpay-Nonce");
        //微信传递过来的签名
        String signature = request.getHeader("Wechatpay-Signature");
        //证书序列号（微信平台）
        String serialNo = request.getHeader("Wechatpay-Serial");
        //时间戳
        String timestamp = request.getHeader("Wechatpay-Timestamp");

        InputStream is = null;
        try {
            is = request.getInputStream();
            // 构造 RequestParam
            RequestParam requestParam = new RequestParam.Builder()
                    .serialNumber(serialNo)
                    .nonce(nonceStr)
                    .signature(signature)
                    .timestamp(timestamp)
                    .body(body)
                    .build();
            // 如果已经初始化了 RSAAutoCertificateConfig，可以直接使用  config
            NotificationConfig config = wxPayAutoCertificateConfig.rsaAutoCertificateConfig();
            // 初始化 NotificationParser
            NotificationParser parser = new NotificationParser(config);
            // 验签、解密并转换成 Transaction
            Transaction transaction = parser.parse(requestParam, Transaction.class);
            //记录日志信息
            Transaction.TradeStateEnum state = transaction.getTradeState();
            if (!StringUtils.equals("SUCCESS", state.toString())) {
                //通知微信回调失败
                response.getWriter().write("<xml><return_code><![CDATA[FAIL]]></return_code></xml>");
            }
            // 获取锁避免重复更新订单数据
            if (lock.tryLock()) {
                try {
                    //处理重复的通知
                    String transactionId = transaction.getTransactionId();
                    if(transactionId != null){
                        //业务处理
                    }else {
                        throw new Exception("订单信息获取失败----------transactionId");
                    }
                } finally {
                    //要主动释放锁
                    lock.unlock();
                }
            }
            //通知微信回调成功
            response.getWriter().write("<xml><return_code><![CDATA[SUCCESS]]></return_code></xml>");
        } catch (Exception e) {
            e.printStackTrace();
            response.getWriter().write("<xml><return_code><![CDATA[FAIL]]></return_code></xml>");
        }finally {
            is.close();
        }
    }

    @Override
    public Map<String, Object> queryOrderByOutTradeNo(String outTradeNo) {
        QueryOrderByOutTradeNoRequest request = new QueryOrderByOutTradeNoRequest();
        request.setOutTradeNo(outTradeNo);
        request.setSpMchid(wxPayConfig.getMerchantId());
        request.setSubMchid("1673936453");
        // 调用request.setXxx(val)设置所需参数，具体参数可见Request定义
        // 调用接口
        NativePayService service = new NativePayService.Builder().config(wxPayAutoCertificateConfig.rsaAutoCertificateConfig()).build();
        Transaction transaction = service.queryOrderByOutTradeNo(request);
        Map<String, Object> map = new HashMap<>(1);
        map.put("tradeState", transaction.getTradeState());
        return map;
    }

}
